<template>
  <div>
    <el-card shadow="never" style="height: 85vh;">
      <vxe-grid
        v-bind="gridOptions"
        v-on="gridEvents"
        ref="gridRef"
        @checkbox-all="selectAllChangeEvent"
        @checkbox-change="selectChangeEvent"
      >
        <template #action="{ row }">
          <vxe-button
            v-for="btn in inTableButtons"
            :key="btn.code"
            size="small"
            :status="btn.status"
            mode="text"
            :icon="getButtonIcon(btn.code)"
            @click="
              handleRowAction(btn.code, row, {
                openEditPopup: handleEdit,
                addChildMenu: addChildMenu,
                removeRow: handleDelete,
              })
            "
            :content="btn.name"
          ></vxe-button>
          <!-- <vxe-button
            mode="text"
            status="primary"
            icon="vxe-icon-add"
            @click="addChildMenu(row)"
            content="添加子类"
          ></vxe-button>
          <vxe-button
            mode="text"
            status="primary"
            icon="vxe-icon-edit"
            @click="handleEdit(row)"
            content="编辑"
          ></vxe-button> -->
          <vxe-button
            mode="text"
            status="error"
            icon="vxe-icon-delete"
            @click="handleDelete(row)"
            content="删除"
          ></vxe-button>
        </template>
      </vxe-grid>
    </el-card>

    <!-- 新建/编辑 弹窗 -->
    <vxe-modal
      v-model="dialogVisible"
      :title="dialogTitle"
      width="60%"
      :esc-closable="false"
      :mask-closable="false"
      show-footer
    >
      <template #default>
        <vxe-form ref="formRef" v-bind="formOptions"></vxe-form>
      </template>
      <template #footer>
        <vxe-button @click="dialogVisible = false">取消</vxe-button>
        <vxe-button status="primary" @click="submitForm">确定</vxe-button>
      </template>
    </vxe-modal>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, nextTick, computed } from "vue";
import type {
  VxeGridListeners,
  VxeGridProps,
  VxeFormRules,
  VxeGridEvents,
  VxeGridInstance,
} from "vxe-table";
import { queryTreeList, saveTreeEntity, delEntityById } from "@/api"; // 假设你有创建和更新的API
import { ElMessage } from "element-plus";
import { VxeUI, type VxeFormInstance, type VxeFormProps } from "vxe-pc-ui";
import { permToButtons, splitButtonsByLocation } from "@/utils/permission";
import { useTableActions,setupToolbar } from "@/utils/useTableActions";

// ==================== 类型定义 ====================
interface RowVO {
  id?: string | number;
  title: string;
  sort: number;
  createTime?: string;
  remarks?: string;
  parentId?: string | number | null; // 可为空，表示根节点
  children?: RowVO[];
}

interface TreeOption {
  value: string | number;
  label: string;
  disabled?: boolean;
  children?: TreeOption[];
}
interface FormDataVO {
  id?: string | number;
  title: string;
  sort: number;
  remarks: string;
  parentId: string; // 初始化为 null
}

// ==================== 构建 TreeSelect 选项（动态响应）====================
/**
 * 判断 target 是否是 source 的子节点（含自身）
 * @param nodes 当前层级节点
 * @param sourceId 要移动的节点ID（不能选自己和自己的子节点）
 * @param targetId 目标节点ID
 */
const isChildOrSelf = (
  nodes: RowVO[],
  sourceId: string | number,
  targetId: string | number | null | undefined
): boolean => {
  // 如果 targetId 是 null/undefined，说明是根节点，不可能是子节点
  if (targetId == null) return false;

  for (const node of nodes) {
    if (node.id == targetId) return true; // 找到目标，返回 true
    if (node.id == sourceId) continue;
    if (node.children?.length) {
      if (isChildOrSelf(node.children, sourceId, targetId)) return true;
    }
  }
  return false;
};

/**
 * 动态构建 vxe-tree-select 所需的选项结构，并禁用非法选择（如选自己或子节点）
 */
// 替换原来的 treeSelectOptions 函数
const treeSelectOptions = computed(() => {
  const currentId = formData.value.id; // 当前编辑项 ID

  const buildOptions = (nodes: RowVO[]): TreeOption[] => {
    return nodes.map((node) => ({
      value: node.id,
      label: node.title,
      disabled: currentId
        ? isChildOrSelf(treeData.value, currentId, node.id)
        : false,
      children:
        node.children && node.children.length > 0
          ? buildOptions(node.children)
          : undefined,
    }));
  };

  return buildOptions(treeData.value);
});
// ==================== 数据源 ====================
// 弹窗相关
const dialogVisible = ref(false);
const dialogTitle = ref("");
const formRef = ref<VxeFormInstance>();
const treeData = ref<RowVO[]>([]);
const selectedRows = ref<RowVO[]>([]);
const vuePermission = ref<any[]>([]);
const inTableButtons = ref<any[]>([]);
const gridRef = ref<VxeGridInstance<RowVO>>();
const formData = ref<Partial<RowVO>>({
  title: "",
  id: "",
  sort: 0,
  remarks: "",
  parentId: null, // 初始化为 null
});

// 定义表单验证规则
const formRules = reactive<VxeFormRules<RowVO>>({
  title: [{ required: true, message: "名称是必填项" }],
  sort: [
    { required: true, message: "排序是必填项" },
    { type: "number", message: "排序必须是数字" },
  ],
  parentId: [{ required: true, message: "上级部门是必选项" }],
});

// 表单配置（先不填 options）
const formOptions = reactive<VxeFormProps<FormDataVO>>({
  data: formData.value,
  rules: formRules.value,
  items: [
    {
      field: "parentId",
      title: "上级",
      itemRender: {
        name: "VxeTreeSelect",
        props: {
          placeholder: "请选择上级",
          clearable: true,
          multiple: false,
        },
      },
      span: 12,
    },
    {
      field: "title", // ❗你之前写的是 "name"，但数据字段是 title
      title: "名称",
      span: 12,
      itemRender: { name: "VxeInput", props: { placeholder: "请输入名称" } },
    },
    {
      field: "sort",
      title: "排序",
      span: 12,
      itemRender: { name: "VxeNumberInput", props: { min: 0, max: 999 } },
    },
    {
      field: "remarks", // ❗你之前写的是 "remarks"
      title: "备注",
      span: 12,
      itemRender: {
        name: "VxeTextarea",
        props: { autosize: { minRows: 2, maxRows: 4 } },
      },
    },
  ],
});

// ✅ 监听 treeSelectOptions 变化，更新 form 表单项
watch(
  treeSelectOptions,
  (newOptions) => {
    const item = formOptions.items?.find((i) => i.field === "parentId");
    if (item?.itemRender) {
      item.itemRender.props = {
        ...item.itemRender.props,
        options: newOptions,
      };
    }
  },
  { immediate: true }
);

// 表格数据与配置
const gridOptions = reactive<VxeGridProps<RowVO>>({
  border: true,
  size: "mini",
  printConfig: {},
  importConfig: {},
  exportConfig: {},
  treeConfig: {
    rowField: "id",
    childrenField: "children",
  },
  toolbarConfig: {
    buttons: [   ],
  },
  formConfig: {
    data: {
      title: "",
    },
    items: [
      { field: "title", title: "名称", itemRender: { name: "VxeInput" } },
      {
        itemRender: {
          name: "VxeButtonGroup",
          options: [
            { type: "submit", content: "搜索", status: "primary" },
            { type: "reset", content: "重置" },
          ],
        },
      },
    ],
  },
  columns: [
    { type: "checkbox", width: 60 },
    { field: "title", title: "名称", minWidth: 300, treeNode: true },
    { field: "sort", title: "排序" },
    { field: "remarks", title: "备注" }, // 表格中显示描述
    { field: "createTime", title: "创建时间" },
    { title: "操作", minWidth: 200, slots: { default: "action" } },
  ],
  data: [],
});

// ==================== 事件监听 ====================
const { getButtonIcon, handleRowAction } = useTableActions<RowVO>({
  customAction(row) {
    console.log("自定义操作:", row.name);
  },
});
const selectAllChangeEvent: VxeGridEvents.CheckboxAll<RowVO> = ({
  checked,
}) => {
  const $grid = gridRef.value;
  if ($grid) {
    const records = $grid.getCheckboxRecords();
    selectedRows.value = records as unknown as RowVO[];
  }
};

const selectChangeEvent: VxeGridEvents.CheckboxChange<RowVO> = ({
  checked,
}) => {
  const $grid = gridRef.value;
  if ($grid) {
    const records = $grid.getCheckboxRecords();
    selectedRows.value = records as unknown as RowVO[];
  }
};
const gridEvents: VxeGridListeners = {
  formSubmit({ data }) {
    // handleSearch(data);
  },
  formReset({ data }) {
    console.log("表单已重置");
  },
  toolbarButtonClick(params) {
    if (params.code == "add") {
      handleCreate();
    } else if (params.code == "del") {
      if (selectedRows.value.length === 0) {
        ElMessage.warning("请先选择要删除的菜单");
        return;
      }
      const ids = selectedRows.value.map((row) => row.id).join(",");
      removeRow(ids);
    }
  },
};

// 打开新建弹窗 (顶级部门)
const handleCreate = () => {
  dialogTitle.value = "新建";
  formOptions.data = { title: "", sort: 0, remarks: "", parentId: null };
  dialogVisible.value = true;
  nextTick(() => {
    formRef.value?.clearValidate();
  });
};

// 打开编辑弹窗
const handleEdit = (row: RowVO) => {
  Object.assign(formOptions.data, {
    id: row.id,
    parentId: row.parentId,
    title: row.title,
    sort: row.sort,
    remarks: row.remarks || "",
  });

  dialogTitle.value = "编辑";
  dialogVisible.value = true;

  nextTick(() => {
    formRef.value?.clearValidate();
  });
};

// 添加子类
const addChildMenu = async (parent: RowVO) => {
  Object.assign(formOptions.data, {
    id: null, // 新增项无 id
    parentId: String(parent.id),
    title: `子类${(parent.children?.length || 0) + 1}`,
    sort: 0,
    remarks: "",
  });

  dialogTitle.value = "添加子类";
  dialogVisible.value = true;

  await nextTick();

  formRef.value?.clearValidate();
};
// 删除行
const handleDelete = (row: RowVO) => {
  removeRow(String(row.id));
};
const removeRow = (id) => {
  VxeUI.modal.confirm({
    title: "提示",
    content: "确定删除数据吗？",
    mask: false,
    lockView: false,
    onConfirm: async () => {
      const res = await delEntityById(lastSegment.value, { ids: id });
      if (res.code == 0) {
        ElMessage.success("删除成功");
        await reloadMenuData(lastSegment.value);
      } else {
        ElMessage.error(res.message);
      }
    },
  });
};

// 提交表单
const submitForm = async () => {
  if (!formRef.value?.data) {
    ElMessage.error("表单未正确初始化");
    return;
  }

  try {
    const submitData = {
      ...formOptions.data,
      select: formOptions.data?.parentId,
      parentId: formOptions.data?.parentId || null,
    };
    const apiResult = await saveTreeEntity(lastSegment.value, submitData);
    if (apiResult?.code === 0) {
      ElMessage.success(apiResult.message);
      dialogVisible.value = false;
      await reloadMenuData(lastSegment.value);
    } else {
      ElMessage.error(apiResult?.message);
    }
  } catch (err: any) {
    ElMessage.error(err.message);
  }
};

// ==================== 数据加载 ====================
const reloadMenuData = async (datas, searchParams = {}) => {
  try {
    const data = await queryTreeList(datas, searchParams);
    if (Array.isArray(data)) {
      treeData.value = data;
      gridOptions.data = treeData.value;
      gridOptions.toolbarConfig = setupToolbar(vuePermission.value);
    } else {
      gridOptions.data = [];
    }
  } catch (err) {
    ElMessage.error("加载数据失败");
    gridOptions.data = [];
  }
};

const initData = async () => {
  const pathSegments = route.path.split("/").filter(Boolean);
  const permissions = route.meta.permission || [];
  const allButtons = permToButtons(permissions);
  const { toolbarButtons, inTableButtons: ops } =
    splitButtonsByLocation(allButtons);

  vuePermission.value = toolbarButtons;
  inTableButtons.value = ops; // 存入响应式变量
  lastSegment.value = pathSegments.pop() || "";
  await reloadMenuData(lastSegment.value);
};

onMounted(() => {
  initData();
});

// 假设的路由
const route = useRoute();
const lastSegment = ref("");
</script>
